<?php
/**
 * Created by PhpStorm.
 * User: guokunsheng
 * Date: 2022/6/23
 * Time: 上午11:20
 */

namespace app\common\lib\astrolog;

use think\Exception;
use think\Log;

/**
 * Class SuitableLover
 * @package app\common\lib\astrolog
 */
class SuitableLover extends LogicBase
{
    /**
     * 单例
     * @var SuitableLover
     */
    protected static $instance;

    /**
     * 计算报告时产生的错误信息
     * @var string
     */
    protected $error = '';

    /**
     * 用户档案信息
     * @var array
     */
    protected $userRecord = [];

    /**
     * 匹配档案的星盘数据
     * @var array
     */
    protected $astroData = [];

    /**
     * 本命星盘配置
     * @var array
     */
    protected $setting = [
        'natal' => [
            'planet' => [
                [1, 7.5], [1, 6], [1, 3.5], [1, 4], [1, 4], [1, 4.5], [1, 4.5], [1, 2.5], [1, 2.5], [1, 2.5],
                [0, 0], [0, 0], [0, 0], [0, 0], [1, 2.5], [0, 0], [0, 0], [1, 2.5], [1, 2.5], [1, 2.5], [1, 2.5]
            ],
            'phase' => [
                0 => [1, 0], 60 => [1, 0], 90 => [1, 0], 120 => [1, 0], 180 => [1, 0],
                45 => [0, 0], 135 => [0, 0], 30 => [0, 0], 150 => [0, 0], 72 => [0, 0], 144 => [0, 0]
            ],
            'arabic' => [
                [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
                [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
                [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]
            ],
            'h_sys' => 'p',
            'firdaria' => 'default',
            'bound_type' => 'default',
            'ecliptic' => 0,
            'profection_push_direction' => 0,
            'decanates' => 0,
            'ayanamsa' => 0,
            'location_use' => 0
        ],
    ];

    /**
     *  11 =>终极契合型
     *  12 =>甜蜜幸福型
     *  13 =>虐恋型
     * @var int[]
     */
    protected $logicType = [];

    /**
     * 获取实例
     * @return SuitableLover
     */
    public static function getInstance(): SuitableLover
    {
        if (!(self::$instance instanceof self))
        {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 设置号主的档案信息
     * @param array $record
     * @return SuitableLover
     */
    public function setUserRecord($record = []): SuitableLover
    {
        $this->userRecord = $record;
        return $this;
    }

    /**
     *  11 =>终极契合型
     *  12 =>甜蜜幸福型
     *  13 =>虐恋型
     * @param int[] $data
     * @return $this
     */
    public function setLogicType($data = [])
    {
        $this->logicType = $data;
        return $this;
    }

    /**
     * 计算用户的星盘数据
     * @param array $setting 计算星盘数据时，使用的设置
     * @param array $record
     * @return $this
     */
    private function getNatalData($setting = [], $record = []): self
    {
        // 初始化当前星盘数据
        $this->astroData = [];
        $data = Astrolog::getInstance()
            ->setRecode1($record)
            ->setExecPrefix(config('astrolog.prefix'))
            ->setIsAstrolabe(true)
            ->setUserSetting($setting)
            ->setVersion(2)
            ->setGetDatas(['natal'])
            ->getAstroDatas()
            ->getDatas('natal');
        $this->astroData = json_decode(json_encode($data), true);
        return $this;
    }

    /**
     * 获取错误信息
     * 调用方式：$errorMessage = SuitableLover::getInstance()->getError();
     * @return string
     */
    public function getError(): string
    {
        return $this->error;
    }

    /**
     * 报告计算
     * 调用方式：$logicResult = SuitableLover::getInstance()->setUserRecord($recodeDetail)->setLogicType([11, 12, 13])->init();
     * @return array
     */
    public function init()
    {
        // 获取星盘数据
        $this->getNatalData($this->setting, $this->userRecord);
        return $this->caclLogic();
    }

    /**
     * 计算
     * @return array
     */
    protected function caclLogic()
    {
        $res = [];
        try
        {
            if (!empty($this->logicType))
            {
                foreach ($this->logicType as $k => $v)
                {
                    $tmp = [];
                    switch ($v)
                    {
                        case 11:
                            // 终极契合型
                            $planet1InSign = $this->dealText($this->astroData['planets'][1]['in_sign_id']);
                            $planet3InSign = $this->dealText($this->astroData['planets'][3]['in_sign_id']);
                            $house7InSign = $this->dealText($this->astroData['houses'][7]['in_sign_id']);
                            $house7ProtectInSign = $this->dealText($this->astroData['houses'][7]['protect_ancient_insign_id']);
                            $house7ProtectInHouse = $this->dealText($this->astroData['houses'][7]['protect_ancient_inhouse_id']);
                            $house1InSign = $this->dealText($this->astroData['houses'][1]['in_sign_id']);
                            $house8InSign = $this->dealText($this->astroData['houses'][8]['in_sign_id']);
                            $house8ProtectInSign = $this->dealText($this->astroData['houses'][8]['protect_ancient_insign_id']);
                            $tmp = [
                                // 导语 金星落座-月亮落座
                                '1100' . $planet3InSign . $planet1InSign,
                                // 1.你的终极契合型是什么样的人？ 7宫头落座-7宫主落座-7宫主落宫 (最后的忽略)
                                '1101' . $house7InSign . $house7ProtectInSign,
                                // 2.你的终极契合型在感情中的样子 7宫头落座-7宫主落座-7宫主落宫 (最后的忽略)
                                '1102' . $house7InSign . $house7ProtectInSign,
                                // 3.TA和你的契合点 上升星座
                                '1103' . $house1InSign,
                                // 4.终极契合型的事业类型 7宫主落座-7宫主落宫
                                '1104' . $house7ProtectInSign . $house7ProtectInHouse,
                                // 5.终极契合型对事业的态度 7宫主落座-7宫主落宫
                                '1105' . $house7ProtectInSign . $house7ProtectInHouse,
                                // 6.终极契合型的财富来源 8宫头落座-8宫主落座-8宫主落宫 (最后的忽略)
                                '1106' . $house8InSign . $house8ProtectInSign,
                                // 7.终极契合型的家庭观念 7宫头落座-7宫主落座
                                '1107' . $house7InSign . $house7ProtectInSign,
                            ];
                            break;
                        case 12:
                            // 甜蜜幸福型
                            $planet1InSign = $this->dealText($this->astroData['planets'][1]['in_sign_id']);
                            $planet3InSign = $this->dealText($this->astroData['planets'][3]['in_sign_id']);
                            $planet4InSign = $this->dealText($this->astroData['planets'][4]['in_sign_id']);
                            $planet1InHouse = $this->dealText($this->astroData['planets'][1]['in_house_id']);
                            $planet3InHouse = $this->dealText($this->astroData['planets'][3]['in_house_id']);
                            $planet4InHouse = $this->dealText($this->astroData['planets'][4]['in_house_id']);
                            $tmp = [
                                // 导语 金星落座-月亮落座
                                '1200' . $planet3InSign . $planet1InSign,
                                // 你的甜蜜幸福型是什么样的人 金星落座-月亮落座
                                '1201' . $planet3InSign . $planet1InSign,
                                // 你的甜蜜幸福型在感情中的样子 金星落宫-月亮落宫
                                '1202' . $planet3InHouse . $planet1InHouse,
                                // 你们的身体契合度 火星落座-火星落宫
                                '1203' . $planet4InSign . $planet4InHouse,
                            ];
                            break;
                        case 13:
                            // 虐恋型
                            $planet1InSign = $this->dealText($this->astroData['planets'][1]['in_sign_id']);
                            $planet3InSign = $this->dealText($this->astroData['planets'][3]['in_sign_id']);
                            $house5InSign = $this->dealText($this->astroData['houses'][5]['in_sign_id']);
                            $house5ProtectInSign = $this->dealText($this->astroData['houses'][5]['protect_ancient_insign_id']);
                            $tmp = [
                                // 导语 金星落座-月亮落座
                                '1300' . $planet3InSign . $planet1InSign,
                                // 你的虐恋型是什么样的人 金星落座-月亮落座
                                '1301' . $planet3InSign . $planet1InSign,
                                // 虐恋的呈现方式 5宫头落座-5宫主落座
                                '1302' . $house5InSign . $house5ProtectInSign,
                            ];
                            $a = [];
                            $b = [];
                            // 为什么会相爱相杀 金天合刑冲、金海合刑冲、金冥合刑冲
                            if ($this->isPlanetPhasePlanet($this->astroData['planets'], 3, 7, [0, 90, 180]))
                            {
                                $p_t = $this->phaseToIndex($this->astroData['planets'][3]['phase']['3-7']['phase_e']);
                                $a[] = '1303000307' . $p_t . '00';
                                $b[] = '1303000307' . $p_t . '01';
                            }
                            if ($this->isPlanetPhasePlanet($this->astroData['planets'], 3, 8, [0, 90, 180]))
                            {
                                $p_t = $this->phaseToIndex($this->astroData['planets'][3]['phase']['3-8']['phase_e']);
                                $a[] = '1303000308' . $p_t . '00';
                                $b[] = '1303000308' . $p_t . '01';
                            }
                            if ($this->isPlanetPhasePlanet($this->astroData['planets'], 3, 9, [0, 90, 180]))
                            {
                                $p_t = $this->phaseToIndex($this->astroData['planets'][3]['phase']['3-9']['phase_e']);
                                $a[] = '1303000309' . $p_t . '00';
                                $b[] = '1303000309' . $p_t . '01';
                            }
                            // 相位词条分ab两类词条，词条按先a后b排列
                            $tmp = array_merge($tmp, $a, $b);
                            // 为什么会相爱相杀 金星落座-月亮落座
                            $tmp[] = '130301' . $planet3InSign . $planet1InSign;
                            break;
                    }
                    $res[$v] = $tmp;
                }
            }
        }
        catch (Exception $e)
        {
            $res = [];
            Log::write($e->getMessage() . '[' . $e->getFile() . ':' . $e->getLine() . ']', 'error', true);
        }
        return $res;
    }

    /**
     * 仅获取导语
     * 调用方式 $introCode = SuitableLover::getInstance()->setUserRecord($recodeDetail)->getIntroduction();
     * @param int $type
     * @return string
     */
    public function getIntroduction($type = 11)
    {
        try
        {
            $planet1InSign = $this->dealText($this->astroData['planets'][1]['in_sign_id']);
            $planet3InSign = $this->dealText($this->astroData['planets'][3]['in_sign_id']);
            switch ($type)
            {
                case 12:
                    // 导语 金星落座-月亮落座
                    $code = '1200' . $planet3InSign . $planet1InSign;
                    break;
                case 13:
                    // 导语 金星落座-月亮落座
                    $code = '1300' . $planet3InSign . $planet1InSign;
                    break;
                default:
                    // 导语 金星落座-月亮落座
                    $code = '1100' . $planet3InSign . $planet1InSign;
                    break;
            }
        }
        catch (Exception $e)
        {
            Log::write($e->getMessage() . '[' . $e->getFile() . ':' . $e->getLine() . ']', 'error', true);
            $code = '';
        }
        return $code;
    }

    /**
     * 数字保持两位
     * @param $num
     * @return string
     */
    private function dealText($num): string
    {
        return $num > 9 ? (string)$num : '0' . $num;
    }

    /**
     * 获取相位索引
     * @param $phase
     * @return string
     */
    private function phaseToIndex($phase)
    {
        $text = '';
        switch ($phase)
        {
            case 0:
                $text = '00';
                break;
            case 60:
                $text = '01';
                break;
            case 90:
                $text = '02';
                break;
            case 120:
                $text = '03';
                break;
            case 180:
                $text = '04';
                break;
        }
        return $text;
    }
}
